'use strict';
class WekMapPolyFill {
    constructor() {
        if(this === void 0) {
            throw new TypeError("Constructor WeakMap requires 'new'");
        }
        this._id = genId('_WeakMap');
        this._polyfill = true;
        if(arguments.length > 0) {
            throw new TypeError('WeakMap iterable is not supported');
        }
    }

    delete(key) {
        checkInstance(this, 'delete');

        if (!isObject(key)) {
            return false;
        }

        var entry = key[this._id];
        if (entry && entry[0] === key) {
            delete key[this._id];
            return true;
        }

        return false;
    }

    get(key) {
        checkInstance(this, 'get');

        if (!isObject(key)) {
            return void 0;
        }

        var entry = key[this._id];
        if (entry && entry[0] === key) {
            return entry[1];
        }

        return void 0;
    }

    has(key) {
        checkInstance(this, 'has');

        if (!isObject(key)) {
            return false;
        }

        var entry = key[this._id];
        return !!(entry && entry[0] === key);
    }

    set(key, value) {
        checkInstance(this, 'set');

        if (!isObject(key)) {
            throw new TypeError('Invalid value used as weak map key');
        }

        var entry = key[this._id];
        if (entry && entry[0] === key) {
            entry[1] = value;
            return this;
        }

        defineProperty(key, this._id, [key, value]);
        return this;
    }
}

function defineProperty(object, name, value) {
    if(Object.defineProperty) {
        Object.defineProperty(object, name, {
            configurable: true,
            writable: true,
            value: value
        });
    } else {
        object[name] = value;
    }
}

function checkInstance(x, methodName) {
    if (!isObject(x) || !Object.prototype.hasOwnProperty.call(x, '_id')) {
        throw new TypeError(
            methodName + ' method called on incompatible receiver ' +
            typeof x
        );
    }
}

function isObject(x) {
    return Object(x) === x;
}

function genId(prefix) {
    return prefix + '_' + rand() + '.' + rand();
}

function rand() {
    return Math.random().toString().substring(2);
}

export {WekMapPolyFill};
